/**
 * 文件名：AbstractProcess.java
 *
 * 创建人：Elvin Zhao - 279152260@qq.com
 *
 * 创建时间：2019年1月2日 下午3:17:12
 *
 * 版权所有：FNII
 */
package com.z100h.supplychain.core.process;

import java.util.List;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.jeeplus.core.facade.FacadeException;
import com.z100h.supplychain.core.Evidence;
import com.z100h.supplychain.core.EvidenceLockState;
import com.z100h.supplychain.core.EvidenceState;
import com.z100h.supplychain.core.ResourceLockState;
import com.z100h.supplychain.core.ResourceStockoutLockState;

/**
 * 
 * [描述信息：说明类的基本功能]
 *
 * @author Elvin Zhao - 279152260@qq.com
 * @version 1.0 Created on 2019年1月2日 下午7:24:18
 */
public abstract class AbstractReceiptProcess<T extends Evidence> extends BaseProcess {

	/**
	 * 功能实现描述
	 * 
	 * @param args
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年1月2日 下午3:17:12
	 */
	public static void main(String[] args) {

	}

	/**
	 * 创建 单据
	 * 
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年1月2日 下午3:29:43
	 */
	protected abstract String createEvidence(T evidence, EvidenceState evidenceState);

	/**
	 * 关联 单据 与 资源
	 * 由单子 生产 资源
	 * 
	 * @param evidenceId
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年1月2日 下午3:30:03
	 */
	protected abstract void associateEvidenceWithResource(T evidence, final String evidenceId, ResourceStockoutLockState resourceStockoutLockState);

	/**
	 * 入库单前置流程
	 * 
	 * @param evidence
	 * @return
	 * @throws Throwable
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年1月10日 下午8:08:17
	 */
	public T preCreateProcess(final T evidence) throws Throwable {
		createEvidence(evidence, EvidenceState.CREATE);
		return evidence;
	}

	/**
	 * 独立入库流程 和 采购后续流程
	 * 1.创建凭据
	 * 2.生成res资源+凭证关联关系+仓库信息
	 * 3.检查凭据锁
	 * 4.锁资源
	 * 5.生成日志
	 * 
	 * @param evidence
	 * @return
	 * @throws Throwable
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年1月3日 下午6:37:05
	 */
	@Transactional(readOnly = false)
	public T createProcess(final T evidence) throws Throwable {

		String evidenceId = evidence.getEvidenceId();
		/**
		 * 判断采购单是否生成了
		 */
		if (evidence.getEvidenceId() == null) {
			evidenceId = createEvidence(evidence, EvidenceState.CREATE);
		}

		associateEvidenceWithResource(evidence, evidenceId, ResourceStockoutLockState.UNLOCK);

		List<String> luckedResourceIds = checkResource(evidenceId, EvidenceLockState.UNLOCK,
				ResourceStockoutLockState.UNLOCK);

		if (CollectionUtils.isEmpty(luckedResourceIds)) {
			Boolean resourceLockState = lockResource(evidenceId, EvidenceLockState.LOCK);

			if (resourceLockState) {
				resourceLogging(evidenceId, ResourceLockState.LOCK);
			} else {
				throw new FacadeException("失败：资源锁定异常！");
			}
		} else {
			throw new FacadeException("失败：资源存在锁定状态！");
		}
		return evidence;
	}

	/**
	 * 1.资源解锁
	 * 2.确认资源日志 刷resourcelock
	 * 3.检查资源日志 是否有锁
	 * 4.刷单子
	 * 
	 * @param evidenceId
	 * @return
	 * @throws Throwable
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年1月3日 下午6:44:26
	 */
	public void confirmProcess(final List<String> resourceIds, final String evidenceId) throws FacadeException {

		List<String> lockedResourceIds = checkResource(resourceIds, evidenceId, EvidenceLockState.LOCK,
				ResourceStockoutLockState.UNLOCK);

		if (CollectionUtils.isEmpty(lockedResourceIds)) {
			
			Boolean resourceUnlockState = unlockResource(resourceIds, EvidenceLockState.UNLOCK);

			if (resourceUnlockState) {
				resourceLogService.confirmResourceLogging(resourceIds, evidenceId);
				Integer checkNum = resourceLogService.checkConfirmResourceLogging(evidenceId);
				if (checkNum.equals(0)) {
					finishEvidence(evidenceId, EvidenceState.FINISH);
				}
			} else {
				throw new FacadeException("失败：确认入库资源解锁异常！");
			}
			
		}else {
			throw new FacadeException("失败：确认入库资源存在异常！");
		}
		
	}
		/**
		 * 1.批量资源解锁 按单子来
		 * 2.确认资源日志 刷resourcelock
		 * 3.检查资源日志 是否有锁
		 * 4.刷单子
		 * 
		 * @param evidenceId
		 * @return
		 * @throws Throwable
		 * @author: Elvin Zhao - 279152260@qq.com 
		 * @date: Created on 2019年1月3日 下午6:44:26
		 */
		public void confirmProcess(final String evidenceId) throws FacadeException {

//			List<String> lockedResourceIds = checkResource(null, evidenceId, EvidenceLockState.LOCK,
//					ResourceStockoutLockState.UNLOCK);

//			if (CollectionUtils.isEmpty(lockedResourceIds)) {
				
				Boolean resourceUnlockState = unlockResourceByEid(evidenceId, EvidenceLockState.UNLOCK);

				if (resourceUnlockState) {
					resourceLogService.confirmResourceLoggingByEid(evidenceId);
					Integer checkNum = resourceLogService.checkConfirmResourceLogging(evidenceId);
					if (checkNum.equals(0)) {
						finishEvidence(evidenceId, EvidenceState.FINISH);
					}
				} else {
					throw new FacadeException("失败：确认入库资源解锁异常！");
				}
				
//			}else {
//				throw new FacadeException("失败：确认入库资源存在异常！");
//			}
//		
		
		
	}

}
